iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0
AI/ ML & Data

基於人工智慧與深度學習對斑馬魚做行為分析系列 第 13

Day 13 yolo四隻斑馬魚辨識行為

  • 分享至 

  • xImage
  •  

今天是第十三天我們可以寫一些yolo辨識四隻斑馬魚的行為分析,以下是程式碼

import cv2
import numpy as np
from ultralytics import YOLO
from collections import defaultdict

# 載入 YOLOv8 模型
model = YOLO('yolov8n.pt')  # 使用 YOLOv8 的預訓練模型

# 初始化追蹤資料結構
zebrafish_tracks = defaultdict(list)

# 讀取影片
video_path = "zebrafish_video.mp4"  # 您的斑馬魚影片路徑
cap = cv2.VideoCapture(video_path)

# 影片寫入初始化
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('zebrafish_tracking_output.mp4', fourcc, 20.0, (int(cap.get(3)), int(cap.get(4))))

frame_count = 0

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    frame_count += 1
    # 執行 YOLO 辨識
    results = model(frame)

    # 過濾出斑馬魚的檢測結果
    zebrafish_results = [r for r in results.xyxy if int(r[5]) == 0]  # 假設斑馬魚的類別 ID 為 0

    # 更新斑馬魚的追蹤軌跡
    for i, r in enumerate(zebrafish_results[:4]):  # 只追蹤前四隻
        x1, y1, x2, y2, conf, cls = map(int, r)
        cx, cy = (x1 + x2) // 2, (y1 + y2) // 2  # 計算中心點
        zebrafish_tracks[i].append((cx, cy))

        # 畫出斑馬魚的框和中心點
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
        cv2.circle(frame, (cx, cy), 5, (0, 0, 255), -1)
        cv2.putText(frame, f"Fish {i+1}", (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

    # 畫出斑馬魚的運動軌跡
    for i, track in zebrafish_tracks.items():
        if len(track) > 1:
            for j in range(1, len(track)):
                cv2.line(frame, track[j-1], track[j], (255, 0, 0), 2)

    # 顯示結果影像
    cv2.imshow("Zebrafish Detection and Tracking", frame)
    out.write(frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
out.release()
cv2.destroyAllWindows()

1. 載入所需的庫

import cv2
import numpy as np
from ultralytics import YOLO
from collections import defaultdict
  • cv2:OpenCV 庫,用於影像處理與顯示。
  • numpy:數值計算庫,在這裡並未直接使用,但通常會與影像處理一起使用。
  • ultralytics:這個庫包含 YOLOv8 模型,用於物體辨識。
  • defaultdict:從 collections 模組導入,用來追蹤每一隻斑馬魚的運動軌跡。

2. 載入 YOLOv8 模型

model = YOLO('yolov8n.pt')  # 使用 YOLOv8 的預訓練模型
  • 這行程式碼載入了一個 YOLOv8 預訓練模型 (yolov8n.pt) 來進行物體辨識。這個模型可以辨識出多種物體,包括我們關注的斑馬魚。

3. 初始化追蹤資料結構

zebrafish_tracks = defaultdict(list)
  • 使用 defaultdict(list) 來初始化一個用於儲存斑馬魚運動軌跡的字典。每個斑馬魚的索引將對應一個包含多個 (x, y) 坐標點的列表,用於記錄每一幀中斑馬魚的中心位置。

4. 讀取影片和準備輸出

video_path = "zebrafish_video.mp4"  # 您的斑馬魚影片路徑
cap = cv2.VideoCapture(video_path)

fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('zebrafish_tracking_output.mp4', fourcc, 20.0, (int(cap.get(3)), int(cap.get(4))))
  • 使用 OpenCV 的 VideoCapture 來讀取影片,video_path 是您要分析的影片路徑。
  • 為了保存結果影片,使用 VideoWriter 初始化輸出檔案。fourcc 定義了影片的編碼格式,out 是保存結果影片的物件。

5. 逐幀處理影片

frame_count = 0

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    frame_count += 1
    # 執行 YOLO 辨識
    results = model(frame)
  • 使用 while 迴圈來逐幀讀取影片並進行處理。
  • cap.read() 讀取每一幀並存入 frame,如果讀取失敗則退出迴圈。
  • 使用 model(frame) 來執行 YOLO 辨識並獲得每一幀的結果。

6. 過濾與追蹤斑馬魚

zebrafish_results = [r for r in results.xyxy if int(r[5]) == 0]  # 假設斑馬魚的類別 ID 為 0

for i, r in enumerate(zebrafish_results[:4]):  # 只追蹤前四隻
    x1, y1, x2, y2, conf, cls = map(int, r)
    cx, cy = (x1 + x2) // 2, (y1 + y2) // 2  # 計算中心點
    zebrafish_tracks[i].append((cx, cy))

    # 畫出斑馬魚的框和中心點
    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
    cv2.circle(frame, (cx, cy), 5, (0, 0, 255), -1)
    cv2.putText(frame, f"Fish {i+1}", (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
  • 在這裡,我們過濾出 YOLO 模型辨識出的斑馬魚(假設類別 ID 為 0),並限制只追蹤前四隻。
  • 每一幀中,程式計算斑馬魚的框 (bounding box) 和中心點 (cx, cy),並將其添加到 zebrafish_tracks 中以追蹤斑馬魚的運動。
  • 使用 cv2.rectanglecv2.circle 在影像上畫出框和中心點,同時在框的上方標註斑馬魚的編號。

7. 畫出運動軌跡

for i, track in zebrafish_tracks.items():
    if len(track) > 1:
        for j in range(1, len(track)):
            cv2.line(frame, track[j-1], track[j], (255, 0, 0), 2)
  • 遍歷每一隻斑馬魚的追蹤紀錄,使用 cv2.line 畫出牠們的運動軌跡。這可以讓您看到斑馬魚在多幀影片中的移動路徑。

8. 顯示與儲存結果

cv2.imshow("Zebrafish Detection and Tracking", frame)
out.write(frame)

if cv2.waitKey(1) & 0xFF == ord('q'):
    break
  • 每一幀都會顯示在窗口中,並使用 out.write(frame) 將其寫入結果影片檔案。
  • 如果使用者按下 q 鍵,程式會中止影片處理。

9. 釋放資源

cap.release()
out.release()
cv2.destroyAllWindows()
  • 最後,釋放影片讀取與寫入的資源,並關閉所有 OpenCV 顯示窗口。

總結

這個程式的核心是利用 YOLOv8 進行斑馬魚的辨識,並在每一幀中追蹤多隻斑馬魚的運動軌跡。它既實現了實時的物體辨識,也處理了多幀的軌跡追蹤,使我跟使用者能夠深入分析斑馬魚的行為模式。


上一篇
day 12 lstm yolo 使用者視窗
下一篇
day 14 yolo辨識氣候變遷
系列文
基於人工智慧與深度學習對斑馬魚做行為分析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言